﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Resources;
using System.Windows.Forms;
using BrightIdeasSoftware;
using TSites.GUI.Entities;
using TSites.GUI.Enums;
using TSites.GUI.Languages;
using TSites.Offices;
using TSites.Service.Common.Utils;
using TSites.Service.Entities;
using VNMessageBox;

namespace TSites.GUI
{
	public partial class frmExport : Form
	{
		public frmExport()
		{
			InitializeComponent();
		}

		private Company _company;
		private LANGUAGE _language = ConfigurationSingleton.Instance.Language;
		public frmExport(Company com)
			: this()
		{
			_company = com;
			FillData(_company);
			if (_language == LANGUAGE.English)
			{
				tabPaymentMethod.SelectedIndex = 1;
			}
		}

		#region Methods
		
		private void ApplyResource()
		{
			CultureInfo culture = CultureInfoFactory.GetInstance();
			ResourceManager rm = new ResourceManager(CultureInfoFactory.BASEDNAME, typeof(frmExport).Assembly);

			this.Text = rm.GetString("frmExport", culture);
			grpClientInfo.Text = rm.GetString("ClientInfo", culture);

			lblTaxCode.Text = rm.GetString("ClientTaxCode", culture) + ":";
			lblContractNo.Text = rm.GetString("ClientContractNo", culture) + ":";
			lblCompanyName.Text = rm.GetString("ClientName", culture) + ":";
			lblRepresentedBy.Text = rm.GetString("ClientRepresentedBy", culture) + ":";
			lblPosition.Text = rm.GetString("ClientPosition", culture) + ":";
			txtAuditTotalFee.WaterMark = rm.GetString("RequiredField", culture);

			btnExport.Text = rm.GetString("btnExport", culture);
			btnPreview.Text = rm.GetString("Preview", culture);
			btnPrint.Text = rm.GetString("Print", culture);

			grbContractType.Text = rm.GetString("ContractType", culture);
			// audit parameters
			ApplyAuditResource(rm, culture);

			//
			chkVietnames.Text = rm.GetString("Vietnames", culture);
			chkEnglish.Text = rm.GetString("English", culture);
		}

		private void ApplyAuditResource(ResourceManager rm, CultureInfo culture)
		{
			lblAuditGeneral.Text = rm.GetString("AuditGeneral", culture) + ":";
			lblAuditContractDate.Text = rm.GetString("AuditContractDate", culture) + ":";
			lblAuditArticle1.Text = rm.GetString("AuditArticle1", culture) + ":";
			lblAuditFinanYearEnd.Text = rm.GetString("AuditFinanYearEnd", culture) + ":";
			lblAuditArticle2.Text = rm.GetString("AuditArticle2", culture) + ":";
			lblAuditTotalFee.Text = rm.GetString("AuditTotalFee", culture) + ":";
			lblVNToltalFeeString.Text = rm.GetString("VNTotalFeeString", culture) + ":";
			lblENToltalFeeString.Text = rm.GetString("ENTotalFeeString", culture) + ":";

			grbAuditContract.Text = rm.GetString("AuditContract", culture);
			lblAuditContract.Text = rm.GetString("AuditContract", culture);

			tpageAuditVN.Text = rm.GetString("AuditVN", culture);
			tpageAuditEN.Text = rm.GetString("AuditEN", culture);
			lblAuditVNDesc.Text = lblAuditENDesc.Text = rm.GetString("AuditDescription", culture) + ":";
			colVNTime.Text = colENTime.Text = rm.GetString("AuditTime", culture);
			colVNPaymentMethod.Text = colENPaymentMethod.Text = rm.GetString("AuditPaymentMethod", culture);

			lblAuditArticle6.Text = rm.GetString("AuditArticle6", culture) + ":";
			lblAuditAuditorDate.Text = rm.GetString("AuditAuditorReport", culture) + ":";

			// default value of audit contract
			txtAuditVNDesc.Text = rm.GetString("DefaultVNAuditDesc", culture);
			txtAuditENDesc.Text = rm.GetString("DefaultENAuditDesc", culture);

			olvAuditVNPaymentMethod.SetObjects(new AuditPaymentMethod[] 
			{
				new AuditPaymentMethod 
				{ 
					Time = rm.GetString("DefaultVNTime1", culture),
					MethodOfPayment = rm.GetString("DefaultVNPaymentMethod1", culture)
				},
				new AuditPaymentMethod 
				{ 
					Time = rm.GetString("DefaultVNTime2", culture),
					MethodOfPayment = rm.GetString("DefaultVNPaymentMethod2", culture)
				}
			});
			olvAuditENPaymentMethod.SetObjects(new AuditPaymentMethod[] 
			{
				new AuditPaymentMethod 
				{ 
					Time = rm.GetString("DefaultENTime1", culture),
					MethodOfPayment = rm.GetString("DefaultENPaymentMethod1", culture)
				},
				new AuditPaymentMethod 
				{ 
					Time = rm.GetString("DefaultENTime2", culture),
					MethodOfPayment = rm.GetString("DefaultENPaymentMethod2", culture)
				}
			});
		}

		private void RemovePaymentMethod()
		{
			ObjectListView olvActive, olvPassive;
			if (tabPaymentMethod.SelectedIndex == 0)
			{
				olvActive = olvAuditVNPaymentMethod;
				olvPassive = olvAuditENPaymentMethod;
			}
			else
			{
				olvActive = olvAuditENPaymentMethod;
				olvPassive = olvAuditVNPaymentMethod;
			}

			if (olvActive.SelectedObject != null)
			{
				int index = olvActive.SelectedIndex;
				// remove in Active olv
				olvActive.RemoveObject(olvActive.SelectedObject);
				// remove in Passive olv
				List<AuditPaymentMethod> passiveModels = olvPassive.Objects.Cast<AuditPaymentMethod>().ToList();
				if (passiveModels.Count >= index)
				{
					passiveModels.RemoveAt(index);
					olvPassive.SetObjects(passiveModels); // re-binding
				}
			}
		}

		private void FillData(Company com)
		{
			if (com != null)
			{
				txtTaxCode.Text = com.TaxCode;
				if (com.ContractNos != null && com.ContractNos.Count > 0)
				{
					cbxContractNo.DataSource = com.ContractNos;
					cbxContractNo.SelectedIndex = 0;
				}
				else
				{
					btnExport.Enabled = btnPrint.Enabled = false;
				}
				txtRepresentedBy.Text = com.RepresentedBy;
				
				if (_language == LANGUAGE.Vietnames)
				{
					txtCompanyName.Text = com.VietnamesName;
					txtPosition.Text = com.VietnamesPosition;
				}
				else
				{
					txtCompanyName.Text = com.EnglishName;
					txtPosition.Text = com.EnglishPosition;
				}
			}
		}

		private bool GetAuditContractParams(ref AuditContractParam auditParams, LANGUAGE language)
		{
			errorProvider1.Clear();

			string totalFee = txtAuditTotalFee.Text.Trim();
			string vnTotalFeeString = txtAuditVNTotalFeeString.Text.Trim();
			string enTotalFeeString = txtAuditENTotalFeeString.Text.Trim();
			string vnDesc = txtAuditVNDesc.Text.Trim();
			string enDesc = txtAuditENDesc.Text.Trim();
			List<AuditPaymentMethod> vnolvModel = olvAuditVNPaymentMethod.Objects.Cast<AuditPaymentMethod>().ToList();
			List<AuditPaymentMethod> enolvModel = olvAuditENPaymentMethod.Objects.Cast<AuditPaymentMethod>().ToList();
			bool exportVN = chkVietnames.Checked;
			bool exportEN = chkEnglish.Checked;

			CultureInfo culture = CultureInfoFactory.GetInstance();
			ResourceManager rm = new ResourceManager(CultureInfoFactory.BASEDNAME, typeof(frmExport).Assembly);

			bool isValid = true;
			if (totalFee.Length == 0)
			{
				errorProvider1.SetError(txtAuditTotalFee, rm.GetString("RequiredField", culture));
				isValid = false;
			}
			if (vnTotalFeeString.Length == 0)
			{
				errorProvider1.SetError(txtAuditVNTotalFeeString, rm.GetString("RequiredField", culture));
				isValid = false;
			}
			if (enTotalFeeString.Length == 0)
			{
				errorProvider1.SetError(txtAuditENTotalFeeString, rm.GetString("RequiredField", culture));
				isValid = false;
			}
			if (exportVN)
			{
				if (vnDesc.Length == 0)
				{
					tabPaymentMethod.SelectedIndex = 0;
					errorProvider1.SetError(txtAuditVNDesc, rm.GetString("RequiredField", culture));
					isValid = false;
				}
				if (vnolvModel.Count == 0)
				{
					tabPaymentMethod.SelectedIndex = 0;
					errorProvider1.SetError(olvAuditVNPaymentMethod, rm.GetString("RequiredField", culture));
					isValid = false;
				}
			}
			if (exportEN)
			{
				if (enDesc.Length == 0)
				{
					tabPaymentMethod.SelectedIndex = 1;
					errorProvider1.SetError(txtAuditENDesc, rm.GetString("RequiredField", culture));
					isValid = false;
				}
				if (enolvModel.Count == 0)
				{
					tabPaymentMethod.SelectedIndex = 1;
					errorProvider1.SetError(olvAuditENPaymentMethod, rm.GetString("RequiredField", culture));
					isValid = false;
				}
			}
			if (exportVN && exportEN && vnolvModel.Count != enolvModel.Count)
			{
				errorProvider1.SetError(olvAuditVNPaymentMethod, rm.GetString("WrongAuditPaymentMethod", culture));
				errorProvider1.SetError(olvAuditENPaymentMethod, rm.GetString("WrongAuditPaymentMethod", culture));
				isValid = false;
			}
			if (isValid)
			{
				int totalFeeInt;
				IFormatProvider formatProvider = _language == LANGUAGE.Vietnames
					? CultureInfoFactory.VIVNFormat
					: CultureInfoFactory.ENUSFormat;
				isValid = int.TryParse(totalFee, NumberStyles.Any, formatProvider, out totalFeeInt);
				if (isValid)
				{
					auditParams = new AuditContractParam
					{
						ContractDate = dtpAuditContractDate.Value.Date,
						FinanYearEnd = dtpAuditFinanYearEnd.Value.Date,
						TotalFee = totalFeeInt,
						TotalFeeString = language == LANGUAGE.Vietnames ? vnTotalFeeString : enTotalFeeString,
						Description = language == LANGUAGE.Vietnames ? vnDesc : enDesc,
						PaymentMethods = language == LANGUAGE.Vietnames ? vnolvModel : enolvModel,
						AuditorReport = dtpAuditAuditorReport.Value.Date
					};
				}
			}
			return isValid;
		}

		private void ExportContract(CONTRACT_TYPE contractType, LANGUAGE language, string printerName = null)
		{
			ConfigurationSingleton configSingle = ConfigurationSingleton.Instance;
			string templatePath = configSingle.WordTemplateFolder;
			string exportFolder = configSingle.ExportPath;

			string applicationPath = Application.StartupPath;
			string taxCode = _company.TaxCode;

			bool isValid = false;
			BasedContractExporter basedContract = null;
			switch (contractType)
			{
				case CONTRACT_TYPE.AUDIT_CONTRACT:
					AuditContractParam auditParams = null;
					if ((isValid = GetAuditContractParams(ref auditParams, language)))
					{
						basedContract = new AuditContractExpoter(Path.Combine(applicationPath, templatePath),
							Path.Combine(applicationPath, exportFolder), taxCode, _company, auditParams);
					}
					break;

				default:
					break;
			}

			if (isValid && basedContract != null)
			{
				basedContract.ExportAndPrint(language, printerName);
			}
		}

		#endregion

		#region Events
		
		private void frmExport_Load(object sender, EventArgs e)
		{
			ApplyResource();
		}

		private void btnBrowse_Click(object sender, EventArgs e)
		{

		}

		private void txtOutput_MouseClick(object sender, MouseEventArgs e)
		{

		}

		private void btnExport_Click(object sender, EventArgs e)
		{
			errorProvider1.Clear();
			bool exportVN = chkVietnames.Checked;
			bool exportEN = chkEnglish.Checked;
			if (!exportVN && !exportEN)
			{
				CultureInfo culture = CultureInfoFactory.GetInstance();
				ResourceManager rm = new ResourceManager(CultureInfoFactory.BASEDNAME, typeof(frmExport).Assembly);

				errorProvider1.SetError(chkVietnames, rm.GetString("NonCheckLanguages", culture));
				errorProvider1.SetError(chkEnglish, rm.GetString("NonCheckLanguages", culture));
				return;
			}

			btnExport.Enabled = btnPrint.Enabled = false;
			if (exportVN)
			{
				ExportContract(CONTRACT_TYPE.AUDIT_CONTRACT, LANGUAGE.Vietnames);
			}

			if (exportEN)
			{
				ExportContract(CONTRACT_TYPE.AUDIT_CONTRACT, LANGUAGE.English);
			}
			btnExport.Enabled = btnPrint.Enabled = true;
		}

		private void cbxContractNo_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (_company.ContractNos != null)
			{
				_company.SelectedContractNo = _company.ContractNos[cbxContractNo.SelectedIndex];
			}
		}

		#endregion

		#region BackgroundWorker

		private BackgroundWorker m_AsyncWorker = new BackgroundWorker();
		private void InitBackgroundWorker()
		{
			m_AsyncWorker.WorkerReportsProgress = true;
			m_AsyncWorker.WorkerSupportsCancellation = true;
			m_AsyncWorker.ProgressChanged += new ProgressChangedEventHandler
							(bwAsync_ProgressChanged);
			m_AsyncWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler
							(bwAsync_RunWorkerCompleted);
			m_AsyncWorker.DoWork += new DoWorkEventHandler(bwAsync_DoWork);
		}

		private void bwAsync_DoWork(object sender, DoWorkEventArgs e)
		{
			// The sender is the BackgroundWorker object we need it to
			// report progress and check for cancellation.
			BackgroundWorker bwAsync = sender as BackgroundWorker;

			ListView.ListViewItemCollection items = null;
			int iCount = items.Count;

			Company company = null;
			for (int i = 0; i < iCount; i++)
			{
				// Working...
				//company = (Company)items[i].Tag;
				//ExportPdf(company);

				// Periodically report progress to the main thread so that it can
				// update the UI.  In most cases you'll just need to send an
				// integer that will update a ProgressBar,
				// but there is an OverLoad for the ReportProgress function
				// so that you can supply some other information
				// as well, perhaps a status label?
				bwAsync.ReportProgress(Convert.ToInt32((i + 1) * (100.0 / iCount)));

				// Periodically check if a cancellation request is pending.
				// If the user clicks cancel the line
				// m_AsyncWorker.CancelAsync(); if ran above.  This
				// sets the CancellationPending to true.
				// You must check this flag in here and react to it.
				// We react to it by setting e.Cancel to true and leaving.
				if (bwAsync.CancellationPending)
				{
					// Set the e.Cancel flag so that the WorkerCompleted event
					// knows that the process was cancelled.
					e.Cancel = true;
					return;
				}
			}

			bwAsync.ReportProgress(100);
		}

		private void bwAsync_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
		{
			// The background process is complete. We need to inspect
			// our response to see if an error occurred, a cancel was
			// requested or if we completed successfully.
			//DisableControls(false);

			// Check to see if an error occurred in the
			// background process.
			if (e.Error != null)
			{
				CMessageBox.Show(e.Error.Message);
				return;
			}

			// Check to see if the background process was cancelled.
			if (e.Cancelled)
			{
			}
			else
			{
				// Everything completed normally.
				// process the response using e.Result
			}
		}

		private void bwAsync_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			// This function fires on the UI thread so it's safe to edit
			// the UI control directly, no funny business with Control.Invoke.
			// Update the progressBar with the integer supplied to us from the
			// ReportProgress() function.  Note, e.UserState is a "tag" property
			// that can be used to send other information from the
			// BackgroundThread to the UI thread.
			progressBar1.Value = e.ProgressPercentage;
		}
		
		#endregion

		private void txtAuditTotalFee_TextChanged(object sender, EventArgs e)
		{
			string totalFee = txtAuditTotalFee.Text.Trim();
			if (totalFee.Length != 0)
			{
				long totalFeeLong;
				IFormatProvider formatProvider = _language == LANGUAGE.Vietnames
					? CultureInfoFactory.VIVNFormat
					: CultureInfoFactory.ENUSFormat;
				if (long.TryParse(totalFee, NumberStyles.Any, formatProvider, out totalFeeLong))
				{
					txtAuditTotalFee.Text = totalFeeLong.ToString("N0", formatProvider);
					txtAuditTotalFee.SelectionStart = txtAuditTotalFee.TextLength;

					txtAuditVNTotalFeeString.Text = NumberToStringReader.DocTienBangChu(totalFeeLong, " Việt Nam đồng");
					txtAuditENTotalFeeString.Text = NumberToStringReader.ChangeNumericToWords(totalFeeLong).TrimEnd() + " Vietnam dongs";
					return;
				}
			}

			txtAuditVNTotalFeeString.Text = txtAuditENTotalFeeString.Text = string.Empty;
		}

		private void btnAddPaymentMethod_Click(object sender, EventArgs e)
		{
			// vn
			AuditPaymentMethod vnPaymentMethod = new AuditPaymentMethod
			{
				Time = "Lần n",
				MethodOfPayment = string.Empty
			};
			olvAuditVNPaymentMethod.AddObject(vnPaymentMethod);
			// en
			AuditPaymentMethod enPaymentMethod = new AuditPaymentMethod
			{
				Time = "The n",
				MethodOfPayment = string.Empty
			};
			olvAuditENPaymentMethod.AddObject(enPaymentMethod);

			if (tabPaymentMethod.SelectedIndex == 0)
			{
				olvAuditVNPaymentMethod.Focus();
				olvAuditVNPaymentMethod.SelectedObject = vnPaymentMethod;
				olvAuditVNPaymentMethod.EnsureVisible(olvAuditVNPaymentMethod.SelectedIndex);
			}
			else
			{
				olvAuditENPaymentMethod.Focus();
				olvAuditENPaymentMethod.SelectedObject = enPaymentMethod;
				olvAuditENPaymentMethod.EnsureVisible(olvAuditENPaymentMethod.SelectedIndex);
			}
		}

		private void btnRemovePaymentMethod_Click(object sender, EventArgs e)
		{
			RemovePaymentMethod();
		}

		private void olvAuditPaymentMethod_KeyUp(object sender, KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Delete)
			{
				RemovePaymentMethod();
			}
		}

		private void txtAuditTotalFee_KeyPress(object sender, KeyPressEventArgs e)
		{
			e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
		}

		private void btnPrint_Click(object sender, EventArgs e)
		{
			errorProvider1.Clear();
			CultureInfo culture = CultureInfoFactory.GetInstance();
			ResourceManager rm = new ResourceManager(CultureInfoFactory.BASEDNAME, typeof(frmExport).Assembly);

			bool exportVN = chkVietnames.Checked;
			bool exportEN = chkEnglish.Checked;
			if (!exportVN && !exportEN)
			{
				errorProvider1.SetError(chkVietnames, rm.GetString("NonCheckLanguages", culture));
				errorProvider1.SetError(chkEnglish, rm.GetString("NonCheckLanguages", culture));
				return;
			}
			
			string title, message;
			title = rm.GetString("Notice", culture);
			message = rm.GetString("PrintConfirm", culture);
			DialogResult dlgResult;
			if (_language == LANGUAGE.Vietnames)
			{
				dlgResult = CMessageBox.Show(message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			}
			else
			{
				dlgResult = MessageBox.Show(message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
			}

			if (dlgResult == DialogResult.Yes)
			{
				string printerName = ConfigurationSingleton.Instance.DefaultPrinterName;
				if (string.IsNullOrWhiteSpace(printerName))
				{
					message = rm.GetString("EmptyPrinterName", culture);
					if (_language == LANGUAGE.Vietnames)
					{
						CMessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					}
					else
					{
						MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					}
					return;
				}

				btnExport.Enabled = btnPrint.Enabled = false;
				if (exportVN)
				{
					ExportContract(CONTRACT_TYPE.AUDIT_CONTRACT, LANGUAGE.Vietnames, printerName);
				}

				if (exportEN)
				{
					ExportContract(CONTRACT_TYPE.AUDIT_CONTRACT, LANGUAGE.English, printerName);
				}
				btnExport.Enabled = btnPrint.Enabled = true;
			}
		}
	}
}
